/*
 * EK.location
 * Inspired by jQuery history plugin (Taku Sano)
 * 
 * Enrichment Kit @ek.version@ (http://enrichmentkit.com)
 * Copyright (c) 2008 Pink Hominid
 * Licensed under terms of the MIT License (LICENSE.txt)
 * 
 * IE 6.0+, FF 1.5+ Tested
 * 
 * Known issues:
 * 
 * IE 6.0  >> After a manual hash change, history gets whacked and the location
 *            bar address and window title stick
 *         >> Incompatible with Firebug Lite (1.0-b1) due to use of iframe
 *         
 * FF 1.5+ >> After a manual hash change, the location bar address sticks
 */

/**
 * Singleton providing enriched location & history support,
 * including named history entries
 */
EK.location = new function EkLocation() {
    this.debugMode = false;

    this.change = function (callback) {
        if (arguments.length) {
            var isFirstListener = !changeListeners.length;
            changeListeners.push(callback);
            if (isFirstListener) { init(); }
        } else {
            for (var i = 0; i < changeListeners.length; i++) {
                changeListeners[i](location.href);
            }
        }
    };

    this.unbindChange = function (callback) {
        if (arguments.length) {
            var startLength = changeListeners.length;
            for (var i = startLength - 1; i >= 0; i--) {
                if (changeListeners[i] === callback) {
                    changeListeners.splice(i, 1);
                }
            }
        } else { // unbind all
            changeListeners = [];
        }		
	};

    this.getPrevious = function () {
		return lastHref;
	};

    this.replace = function (url) {
        var iframe = getIframe();
        if(iframe) {
            iframe.title = document.title;
            iframe.location.replace(url);
        }
        location.replace(url);
        lastHref = location.href;
    };

    var that = this;
    var changeListeners = [];
    var lastHref = undefined;
    var iframe = undefined;
    
    function init() {
        debug("before init()");

        /* Bootstrap hash if it's not already present.
         * Mozilla's location.hash returns "" if "#" is not followed up with
         * other chars, hence the use of location.href & RegExp
         */
        if (!(/#/.test(location.href))) {
            location.replace(location.href + "#");
        }
        
        var currentHref = location.href;
    
        if(EK.browser.msie) {
            // inject and initialize iframe for IE history
            EK.prepend('<iframe id="ekHistory" src="javascript:\'\'" ' + 
                'style="display: none;"></iframe>', EK.tag("body")[0]);
            var iframe = getIframe();
            iframe.open();
            iframe.close();
            iframe.location.href = currentHref;
        }
    
        EK.location.change();
		
        // pickup any changes to the window title and inject into history
        EK.location.replace(location.href);
    
        debug("after init()");
        
        setTimeout(check, 100);
    }

    function check() {
        var currentHref = location.href;
        var iframe, iframeHref = undefined;
        if(EK.browser.msie) {
            iframe = getIframe();
            if (iframe) { iframeHref = iframe.location.href; }
        }
                    
        if (/^http/.test(currentHref) && (iframeHref ? /^http/.test(iframeHref):true)) {
            if(currentHref != lastHref) {
                debug("before check()");
                
                if(EK.browser.msie) {
                    iframe.open();
                    iframe.close();
                    iframe.location.href = currentHref;
                }
                            
                EK.location.change();
    
                // pickup any changes to the window title and inject into history
                EK.location.replace(location.href);
                
                debug("after check()");
                
            } else if (iframeHref && iframeHref != lastHref) {
                debug("before check()");
    
                location.href = iframeHref;
    
                EK.location.change();
    			
                // pickup any changes to the window title and inject into history
                EK.location.replace(location.href);
                
                debug("after check()");
            }
        }
        setTimeout(check, 100);
    }
    
    function getIframe() {
        var elem = EK.id("ekHistory"); 
        if (elem) { return elem.contentWindow.document; }
        else { return null; }
    }
    
    function debug(msg) {
        if (that.debugMode) {
            EK.debug("EK.location: " + msg);
            EK.debug("EK.location: lastHref = " + lastHref);
            EK.debug("EK.location: currentHref = " + location.href);
            var iframe = getIframe();
            if(iframe) {
                EK.debug("EK.location: iframeHref = " + iframe.location.href);
            }
        }
    }
}();
